package part15;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wcj
 * @Date 2021/5/30 18:13
 * @Version 1.0
 */
public class Part1536 {

    public static void main(String[] args) {
        ProcessRunner<String, Failure1> processors = new ProcessRunner<>();
        for (int i = 0; i < 3; i++) {
            processors.add(new Processor1());
        }

        try {
            System.out.println(processors.processAll());
        } catch (Failure1 failure1) {
            System.out.println(failure1);
        }

        ProcessRunner<Integer, Failure2> processorss = new ProcessRunner<>();
        for (int i = 0; i < 3; i++) {
            processorss.add(new Processor2());
        }

        try {
            System.out.println(processorss.processAll());
        } catch (Failure2 failure2) {
            System.out.println(failure2);
        }
    }
}

/**
 * 因为java的异常机制无法捕获泛型异常，所以我们可以通过类型参数限定边界为Exception等，来让不同的类抛出不同的异常
 *
 * @param <T>
 * @param <E>
 */
interface Processor<T, E extends Exception> {

    /**
     * process
     *
     * @param resultCollector
     * @throws E
     */
    void process(List<T> resultCollector) throws E;
}

class ProcessRunner<T, E extends Exception> extends ArrayList<Processor<T, E>> {
    List<T> processAll() throws E {
        ArrayList<T> resultCollector = new ArrayList<>();
        for (Processor<T, E> teProcessor : this) {
            teProcessor.process(resultCollector);
        }
        return resultCollector;
    }
}

class Failure1 extends Exception {
}

class Processor1 implements Processor<String, Failure1> {
    static int count = 3;

    @Override
    public void process(List<String> resultCollector) throws Failure1 {
        if (count-- > 1) {
            resultCollector.add("Hep!");
        } else {
            resultCollector.add("Ho!");
        }

        if (count < 0) {
            throw new Failure1();
        }
    }
}

class Failure2 extends Exception {
}

class Processor2 implements Processor<Integer, Failure2> {
    static int count = 2;

    @Override
    public void process(List<Integer> resultCollector) throws Failure2 {
        if (count-- > 1) {
            resultCollector.add(47);
        } else {
            resultCollector.add(11);
        }

        if (count < 0) {
            throw new Failure2();
        }
    }
}
